package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"errors"
	"fmt"
)

// 可通过openssl产生
//openssl genrsa -out rsa_private_key.pem 1024
var privateKey = []byte(`
-----BEGIN RSA PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKlQBcqUL0+Ai55HP3gav7/F6z5C5qN4rOEn+bNoIxWpF3cltAHYjmMz9IuThFRkUEFUzXCYNJc/HTw9i22gixduIj9yDEUqFNiMWC0X3bGU8XEdRsRJhIcZegZ2N3AuYzgFyb34x4+rnqcXsA06qF1UGGNYvjOSQ74tqq9IKPxNAgMBAAECgYEApMAMUpotCyRfN03G8by9lwMkrDn3KVx0hMccT7nmYd5eyf5zEVTDAL7+l46ctm3CNkAphAVnL0En1oVglfUhQb8RolorWx3DbO2NGka7Npcdy3fU877OVQf/V2vcVVB7VSSyJtMWTS4h2lWVYM5fa9RzP/zmI1O29AXmK9zfSFUCQQDUzWl8QP4OReMc5sZO/MRXoTJ8EzIxm1B9UBZx/g9hQbkstwaHKMbFPrDqvSTGbBkZVF09m7Qf38crGgHGzvSLAkEAy66ZapGttAfrdreFZh2CnNd7cd3MJm0224qFf6F0LesnkUl9kFNbmVz4E56Ph2MUobrVTYKwaiXbDwA4yZf1hwJAVqn5JbNKRAHORnztkkl6pL1vU/x1WqKIGyC8o1v2Y4NiqIU5UV4X5UhswIybJ3vqlNg4yNhaeQinkjQbOR4blQJAb/fUeIQK5EvyQfnTCHayhXvjbY4LGxiwrnFwv9/GmTOLNdAbiYp5cU5tRYPFzRxHjDzD428zgba7vHxXu2Kg4wJBAKaRjldkIhNOIKEGETWuc0pQo7a8JA7ynu8K+QNY+OHqvdbv9Hfevz5b9Y0ys2L39IfeTYY58qbmDsNs1eJXcEU=
-----END RSA PRIVATE KEY-----
`)

//openssl
//openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
var publicKey = []byte(`
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpUAXKlC9PgIueRz94Gr+/xes+QuajeKzhJ/mzaCMVqRd3JbQB2I5jM/SLk4RUZFBBVM1wmDSXPx08PYttoIsXbiI/cgxFKhTYjFgtF92xlPFxHUbESYSHGXoGdjdwLmM4Bcm9+MePq56nF7ANOqhdVBhjWL4zkkO+LaqvSCj8TQIDAQAB
-----END PUBLIC KEY-----
`)

// 加密
func RsaEncrypt(origData []byte) ([]byte, error) {
	//解密pem格式的公钥
	block, _ := pem.Decode(publicKey)
	if block == nil {
		return nil, errors.New("public key error")
	}
	// 解析公钥
	pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	// 类型断言
	pub := pubInterface.(*rsa.PublicKey)
	//加密
	return rsa.EncryptPKCS1v15(rand.Reader, pub, origData)
}

// 解密
func RsaDecrypt(ciphertext []byte) ([]byte, error) {
	//解密
	block, _ := pem.Decode(privateKey)
	if block == nil {
		return nil, errors.New("private key error!")
	}
	//解析PKCS1格式的私钥
	priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	// 解密
	return rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext)
}

func main() {
	data, _ := RsaEncrypt([]byte("hello world"))
	fmt.Println(base64.StdEncoding.EncodeToString(data))
	fmt.Println("_____")
	origData, _ := RsaDecrypt(data)
	fmt.Println(string(origData))
}
